package com.spa.domain.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.spa.application.command.admin.MassageServiceAddCommand;
import com.spa.application.command.admin.MassageServiceEditCommand;
import com.spa.application.query.admin.MassageServiceQuery;
import com.spa.infrastructure.enums.dict.base.WhetherTypeEnum;
import com.spa.infrastructure.util.StringUtils;
import com.spa.domain.entity.MassageServiceEntity;
import com.spa.domain.entity.MassageServiceFlow;
import com.spa.infrastructure.mapper.MassageServiceFlowMapperStruct;
import com.spa.infrastructure.mapper.MassageServiceMapperStruct;
import com.spa.infrastructure.repository.condition.MassageRefCondition;
import com.spa.infrastructure.repository.condition.MassageServiceCondition;
import com.spa.infrastructure.repository.condition.MassageServiceFlowCondition;
import com.spa.infrastructure.repository.po.MassageRefPO;
import com.spa.infrastructure.repository.po.MassageServiceFlowPO;
import com.spa.infrastructure.repository.po.MassageServicePO;
import com.spa.infrastructure.repository.service.MassageRefRepositoryService;
import com.spa.infrastructure.repository.service.MassageServiceFlowRepositoryService;
import com.spa.infrastructure.repository.service.MassageServiceRepositoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MassageService {

    @Resource
    private MassageServiceRepositoryService massageServiceRepositoryService;

    @Resource
    private MassageRefRepositoryService massageRefRepositoryService;

    @Resource
    private MassageServiceFlowRepositoryService massageServiceFlowRepositoryService;

    public List<MassageServiceEntity> getServiceByMessageId(Long messagistId) {
        List<MassageServicePO> myMessageService = massageServiceRepositoryService.getMyMessageService(messagistId);
        if (CollectionUtil.isEmpty(myMessageService)) {
            return null;
        }
        return BeanUtil.copyToList(myMessageService, MassageServiceEntity.class);
    }


    /**
     * 获取服务分页列表
     *
     * @author: lig
     * @date: 2023/12/9
     */
    public Page<MassageServiceEntity> servicePageList(MassageServiceCondition condition) {
        if (ObjectUtil.isNotEmpty(condition.getMassagistId())) {
            MassageRefCondition refCondition = new MassageRefCondition();
            refCondition.setMassagistId(condition.getMassagistId());
            //获取指定技师的项目ID集
            List<MassageRefPO> serviceIds = massageRefRepositoryService.refList(refCondition);
            if (CollUtil.isNotEmpty(serviceIds)) {
                condition.setServiceIds(serviceIds.stream().map(MassageRefPO::getServiceId).toList());
            }
        }
        condition.setIsDel(WhetherTypeEnum.$0.getCode());
        Page<MassageServicePO> page = massageServiceRepositoryService.pageList(condition);
        return MassageServiceMapperStruct.INSTANCE.po2Entity4Page(page);

    }

    /**
     * 通过技师ID 获取相关服务列表
     *
     * @author: lig
     * @date: 2023/12/9
     */
    public List<MassageServiceEntity> serviceListByMassagistId(Long massagistId) {
        MassageServiceCondition condition = new MassageServiceCondition();

        MassageRefCondition refCondition = new MassageRefCondition();
        refCondition.setMassagistId(massagistId);
        //获取指定技师的项目ID集
        List<MassageRefPO> serviceIds = massageRefRepositoryService.refList(refCondition);
        if (CollUtil.isNotEmpty(serviceIds)) {
            condition.setServiceIds(serviceIds.stream().map(MassageRefPO::getServiceId).toList());
        }
        condition.setIsDel(WhetherTypeEnum.$0.getCode());
        return MassageServiceMapperStruct.INSTANCE.po2Entity4List(massageServiceRepositoryService.list(condition));

    }

    public Page<MassageServiceEntity> page4Admin(MassageServiceQuery query) {
        MassageServiceCondition condition = MassageServiceMapperStruct.INSTANCE.query2Condition(query);
        condition.setIsDel(null);
        Page<MassageServicePO> page = massageServiceRepositoryService.pageList(condition);
        return MassageServiceMapperStruct.INSTANCE.po2Entity4Page(page);
    }

    /**
     * 获取服务详情
     *
     * @author: lig
     * @date: 2023/12/9
     */
    public MassageServiceEntity serviceDetails(MassageServiceCondition condition){
        MassageServiceEntity entity = MassageServiceMapperStruct.INSTANCE.po2Entity(massageServiceRepositoryService.detailsById(condition.getServiceId()));

        if(BeanUtil.isNotEmpty(entity)){
            MassageServiceFlowCondition flowCondition = new MassageServiceFlowCondition();
            flowCondition.setServiceId(entity.getId());
            //组装服务流程
            entity.setMassageServiceFlowList(MassageServiceFlowMapperStruct.INSTANCE.po2Entity4List(massageServiceFlowRepositoryService.list(flowCondition)));

        }

        return entity;
    }

    public MassageServiceEntity infoById(Long id){
        return MassageServiceMapperStruct.INSTANCE.po2Entity(massageServiceRepositoryService.getById(id));
    }


    /**
     * 添加服务项目
     */
    @Transactional
    public void addMassageService(MassageServiceAddCommand command) {
        MassageServicePO massageServicePO = MassageServiceMapperStruct.INSTANCE.command2Po(command);
        massageServicePO.setImg(StringUtils.join(command.getImgList(), ","));
        massageServicePO.setNote(StringUtils.join(command.getNoteList(), "|"));
        massageServicePO.setDeclaration(StringUtils.join(command.getDeclarationList(), "|"));
        massageServicePO.setHighlightsTar(StringUtils.join(command.getHighlightsTarList(), ","));
        massageServicePO.setPrice(command.getPrice());
        massageServicePO.setDiscountPrice(command.getDiscountPrice());
        int random = RandomUtil.randomInt(5000, 20000);
        massageServicePO.setSelectCount(random);
        log.info("MassageServicePO  {}", massageServicePO);
        long massageServiceId = massageServiceRepositoryService.add(massageServicePO);
        command.getFlowList().forEach(flow -> {
            MassageServiceFlowPO po = MassageServiceFlowMapperStruct.INSTANCE.command2Po(flow);
            po.setServiceId(massageServiceId);
            massageServiceFlowRepositoryService.add(po);
        });
    }

    /**
     * 统计全平台服务项目
     * @return 服务项目数量
     */
    public Long countAllMassageService() {
        return massageServiceRepositoryService.countByCondition(new MassageServiceCondition());
    }

    public void switchStatus(Long id) {
        MassageServicePO po = massageServiceRepositoryService.detailsById(id);
        int status = po.getIsDel() == 0 ? 1 : 0;
        MassageServicePO updatePo = new MassageServicePO();
        updatePo.setId(id);
        updatePo.setIsDel(status);
        massageServiceRepositoryService.updateByCondition(updatePo);
    }

    public void updateMassageService(MassageServiceEditCommand command) {
        MassageServicePO massageServicePO = MassageServiceMapperStruct.INSTANCE.command2Po(command);
        massageServicePO.setImg(StringUtils.join(command.getImgList(), ","));
        massageServicePO.setNote(StringUtils.join(command.getNoteList(), "|"));
        massageServicePO.setDeclaration(StringUtils.join(command.getDeclarationList(), "|"));
        massageServicePO.setHighlightsTar(StringUtils.join(command.getHighlightsTarList(), ","));
        massageServicePO.setPrice(command.getPrice());
        massageServicePO.setDiscountPrice(command.getDiscountPrice());
        massageServiceRepositoryService.updateByCondition(massageServicePO);
        MassageServiceFlowCondition condition = new MassageServiceFlowCondition();
        condition.setServiceId(command.getId());
        massageServiceFlowRepositoryService.delete(condition);
        command.getFlowList().forEach(flow -> {
            MassageServiceFlowPO po = MassageServiceFlowMapperStruct.INSTANCE.command2Po(flow);
            po.setServiceId(command.getId());
            massageServiceFlowRepositoryService.add(po);
        });
    }

    public List<MassageServiceEntity> list(MassageServiceCondition condition) {
        return MassageServiceMapperStruct.INSTANCE.po2Entity4List(massageServiceRepositoryService.list(condition));
    }

    public MassageServiceEntity getMassageServiceEntityById(Long id){
        MassageServiceEntity entity = MassageServiceMapperStruct.INSTANCE.po2Entity(massageServiceRepositoryService.getById(id));
        MassageServiceFlowCondition condition = new MassageServiceFlowCondition();
        condition.setServiceId(entity.getId());
        List<MassageServiceFlowPO> massageServiceFlowPOS = massageServiceFlowRepositoryService.list(condition);
        entity.setMassageServiceFlowList(MassageServiceFlowMapperStruct.INSTANCE.po2Entity4List(massageServiceFlowPOS));
        return entity;
    }

    /**
     * 通过服务项目id集合获取服务项目列表
     * @param serviceIds 服务项目id集合
     * @return 服务项目列表
     */
    public List<MassageServiceEntity> getMassageServiceEntityListByIds(List<Long> serviceIds) {
        MassageServiceCondition massageServiceCondition = new MassageServiceCondition();
        massageServiceCondition.setServiceIds(serviceIds);
        List<MassageServiceEntity> massageServiceEntityList = list(massageServiceCondition);
        setMassageServiceFlow(massageServiceEntityList);
        return massageServiceEntityList;
    }

    /**
     * 列表返回项目时配置项目流程
     * @param massageServiceEntityList 服务项目列表
     */
    private void setMassageServiceFlow(List<MassageServiceEntity> massageServiceEntityList) {
        List<Long> ids = massageServiceEntityList.stream().map(MassageServiceEntity::getId).toList();
        List<MassageServiceFlow> massageServiceFlows = getMassageServiceFlowListByIds(ids);
        Map<Long, List<MassageServiceFlow>> map = list2Map4Flow(massageServiceFlows);
        massageServiceEntityList.forEach(massageServiceEntity -> massageServiceEntity.setMassageServiceFlowList(map.get(massageServiceEntity.getId())));
    }

    private List<MassageServiceFlow> getMassageServiceFlowListByIds(List<Long> ids) {
        MassageServiceFlowCondition condition = new MassageServiceFlowCondition();
        condition.setServiceIds(ids);
        return MassageServiceFlowMapperStruct.INSTANCE.po2Entity4List(massageServiceFlowRepositoryService.list(condition));
    }

    /**
     * 服务项目列表 转换为 Map
     * @param massageServiceEntityList 服务项目列表
     * @return id-entity
     */
    public Map<Long, MassageServiceEntity> list2Map(List<MassageServiceEntity> massageServiceEntityList) {
        return massageServiceEntityList.stream().collect(Collectors.toMap(MassageServiceEntity::getId, Function.identity()));
    }

    public Map<Long, List<MassageServiceFlow>> list2Map4Flow(List<MassageServiceFlow> massageServiceFlows) {
        return massageServiceFlows.stream().collect(Collectors.groupingBy(MassageServiceFlow::getServiceId));
    }

    public List<MassageServiceEntity> getMassageList(MassageServiceQuery query) {
        MassageServiceCondition condition = MassageServiceMapperStruct.INSTANCE.query2Condition(query);
        condition.setIsDel(null);
        return MassageServiceMapperStruct.INSTANCE.po2Entity4List(massageServiceRepositoryService.list(condition));
    }
}
